﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Farigola.Engine.TestUnit;
using Farigola.Engine.Reposit;
using System.Threading;
using Farigola.Engine.SystemData.Entity.inst;
using Farigola.Engine.SystemData.Entity;

namespace Farigola.Engine.PersistXml.TestUnit
{
    // [SetUp]
    // [TearDown]

    [TestFixture]
    public class EngineRepositXmlTestUnit
    {
        /// <summary>
        /// General path to save/load project files.
        /// </summary>
        private static string _pathLoadSavePrjFile = "savePrj";

        //---------------------------------------------------------------------
        [Test]
        public void SaveProjectEmptyCloseActiveProject()
        {
            // create a concrete repository, persit data project in a xml file
            //IEngineReposit engineReposit = new EngineRepositXml();

            // create an engine, inject the xml concrete persistence
            Engine engine = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXml(); 
            //EngineCommonTestUnit.CreateInitEngine(engineReposit);
            Workspace wksp = engine.GetWorkspace();
		
		    // create a project
		    Project prj= wksp.CreateActiveProject("prj");

            // save the project
            bool res = wksp.SaveActiveProject(_pathLoadSavePrjFile + @"\MyProject.zip");
            Assert.IsTrue(res, "The save of the project should be done: " + _pathLoadSavePrjFile + @"\MyProject.zip");

            // close (and clear) the active project
            res = wksp.CloseActiveProject();
            Assert.IsTrue(res, "The project should be closed.");
            // need to do that
            prj = null;

            // get the active project
            prj= wksp.GetActiveProject();
            Assert.IsNull(prj, "No active project expected after the close.");
        }

        //---------------------------------------------------------------------
        [Test]
        public void SavePrjButFileNameWrong()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            wksp.CreateActiveProject("prj");

            // save the project
            bool res = wksp.SaveActiveProject(@"qsd\\qsdqd");
            Assert.IsFalse(res, "The save is not possible, the file name is wrong.");

            // get the last error occurs
            AppError err = wksp.GetLastError();
            Assert.IsNotNull(err, "The save of the project should failed.");

            // check the error code
            Assert.AreEqual(ProjectRepositXmlDef.ErrorCode.UnableToSaveFile.ToString(), err.Code, "The err code should be FileName Wron.");
        }

        //---------------------------------------------------------------------
        [Test]
        public void LoadPrjButFileNotExists()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            // load a project
            Project projet= wksp.LoadActiveProject("sdfsdfsdfprj");
            Assert.IsNull(projet, "The load of the project should fail, the file name is wrong.");

            // get the last error occurs
            AppError err = wksp.GetLastError();
            Assert.IsNotNull(err, "An error should exists because The load of the project has failed.");

            // check the error code
            Assert.AreEqual(ProjectRepositXmlDef.ErrorCode.FileNotExist.ToString(), err.Code, "The err code should be file not exists.");
        }

        //---------------------------------------------------------------------
        [Test]
        public void SaveLoadProjectEmpty()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // save the project
            string fileName = _pathLoadSavePrjFile + @"\MyProjectEmpty.zip";

            bool res = wksp.SaveActiveProject(fileName);
            // to be sure that the OS release the file
            //Thread.Sleep(200);

            AppError err = wksp.GetLastError();

            string errMsg = "";
            if (err != null)
                errMsg = "ErrCode=" + err.Code + ", ErrParam=" + err.Param + ", Param2=" + err.Param2;
                //sSystem.Console.WriteLine("Err=" + err.Code);

            Assert.IsTrue(res, "The save of the project should be done: " + fileName + ", ErrMsg=" + errMsg);
            // close (and clear) the active project
            res = wksp.CloseActiveProject();
            prj = null;

            // load a project
            Project prjLoad = wksp.LoadActiveProject(fileName);
            Assert.IsNotNull(prjLoad, "The load of the project should ends ok.");

            //fileName = _pathLoadSavePrjFile + @"\MyProjectEmptySave.zip";
            //wksp.SaveActiveProject(fileName);
        }

        //---------------------------------------------------------------------
        [Test]
        public void SaveLoadProjectEmptyCheckContent()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // save the project
            string fileName = _pathLoadSavePrjFile + @"\PrjEmpty2.zip";
            wksp.SaveActiveProject(fileName);
            EntInstFolder rootFolder = prj.GetProjectStruct().GetRootFolder();
            EntityId id = rootFolder.GetId();
            string name = rootFolder.GetName();
            wksp.CloseActiveProject();
            prj = null;

            // load the project
            Project prjLoad = wksp.LoadActiveProject(fileName);

            // check the 
            EntInstFolder rootFolderLoad = prjLoad.GetProjectStruct().GetRootFolder();

            Assert.IsTrue(rootFolderLoad.GetId().IdAreEquals(id), "Id of the root folder should be equals.");
            Assert.AreEqual(rootFolderLoad.GetName(), name, "Name of the root folder should be equals.");
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Save an ent inst string.
        /// </summary>
        [Test]
        public void SaveLoadProjectOneEntInstString()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // add a string to the project
            EntInstString entString= prj.createEntInstString("str");
            prj.SetValToEntInstString(entString, "bonjour");

            // save the project
            string fileName = _pathLoadSavePrjFile + @"\PrjWithOneString.zip";

            // save and close the project
            bool res = wksp.SaveActiveProject(fileName);
            res = wksp.CloseActiveProject();
            prj = null;

            // load the project
            Project prjLoad = wksp.LoadActiveProject(fileName);

            // check details
            EntInstString entStringLoad = prjLoad.GetEntityFinder().FindEntInstStringByName("str");
            Assert.IsNotNull(entStringLoad, "The string 'str' should exists in the saved/load project.");
            Assert.IsTrue(entString.GetId().IdAreEquals(entStringLoad.GetId()), "The id of the string should be the same after the save/load operation.");

            // check the value of the ent string (data value)
            Assert.AreEqual("bonjour", entStringLoad.GetDataValueString().GetValue(), "The value of the ent string should be 'bonjour'.");
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// save and load a prj with a folder in folder.
        /// </summary>
        [Test]
        public void SaveLoadProjectFolderInFolder()
        {
            // create an engine, inject the xml concrete persistence
            Workspace wksp = EngineRepositXmlCommonTestUnit.CreateInitEnginePersistXmlGetWksp();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");
            EntInstFolder folder = prj.createEntInstFolder("fold");
            EntInstFolder folderChild = prj.createEntInstFolder(folder, "foldChild");

            // save the project
            string fileName = _pathLoadSavePrjFile + @"\PrjFolderInFolder.zip";

            // save and close the project
            bool res = wksp.SaveActiveProject(fileName);
            res = wksp.CloseActiveProject();
            //prj = null;

            //--load the project
            Project prjLoad = wksp.LoadActiveProject(fileName);
            // check fold
            EntInstFolder entFolderLoad = prjLoad.GetEntityFinder().FindEntInstFolderByName("fold");
            Assert.IsNotNull(entFolderLoad, "The folder 'fold' should exists after a save/load.");
            
            // checks fold\foldChild
            EntInstFolder entFolderChildLoad = prjLoad.GetEntityFinder().FindEntInstFolderByName(entFolderLoad, "foldChild");
            Assert.IsNotNull(entFolderChildLoad, "The folder 'foldChild' should exists after a save/load.");
        }

        //---------------------------------------------------------------------
        // save an empty project: ok load it and check


        // save on an existing file


    }
}
